﻿using System;
using System.Collections.Generic;
using System.Text;

namespace TLang.Ast
{
    using Values;

    public class RecordLiteral : Node
    {

        public readonly Map<String, Node> Map = new Map<string, Node>();


        public RecordLiteral(List<Node> contents, String file, int start, int end, int line, int col) : base(file, start, end, line, col)
        {
            if (contents.Count % 2 != 0)
            {
                Util.Abort(this, "record initializer must have even number of elements");
            }

            for (int i = 0; i < contents.Count; i += 2)
            {
                Node key = contents[i];
                Node value = contents[i + 1];
                if (key is Keyword)
                {
                    if (value is Keyword)
                    {
                        Util.Abort(value, "keywords shouldn't be used as values: " + value);
                    }
                    else
                    {
                        Map.Put(((Keyword)key).id, value);
                    }
                }
                else
                {
                    Util.Abort(key, "record initializer key is not a keyword: " + key);
                }
            }
        }


        public override Value Interp(Scope s)
        {
            Scope properties = new Scope();
            foreach (var e in Map)
            {
                properties.PutValue(e.Key, e.Value.Interp(s));
            }
            return new RecordType(null, this, properties);
        }

        public override Value Typecheck(Scope s)
        {
            Scope properties = new Scope();
            foreach (var e in Map)
            {
                properties.PutValue(e.Key, e.Value.Typecheck(s));
            }
            return new RecordType(null, this, properties);
        }


        public override String ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(Constants.SQUARE_BEGIN);
            bool first = true;
            foreach (var e in Map)
            {
                if (!first)
                {
                    sb.Append(" ");
                }
                sb.Append(":" + e.Key + " " + e.Value);
                first = false;
            }
            sb.Append(Constants.SQUARE_END);
            return sb.ToString();
        }
    }
}
